<?php
namespace App\Common\Cla\Com\Token;

use App\Common as com;
use App\Common\Cla\Com\Token as nameToken;

class OfSid extends com\Cla\ClaBase {

	public $sid = null;

	/**
	 * ApiToken sid缓存键对象(使用时初始化，调用方法：$this->getTokenKeyDbObj())
	 * @var com\Lib\Cache\KeyDB
	 */
	private $tokenSidKeyDbObj = null;

	public function __construct( string $sid ) {
		$this->sid = $sid;
		//
		parent::__construct();
	}

	/**
	 * 获取Token缓存键对象
	 * @return com\Lib\Cache\KeyDB
	 */
	private function getTokenKeyDbObj(  ) {
		if( $this->tokenSidKeyDbObj === null ){
			$this->tokenSidKeyDbObj = com\Lib\Cache\KeyDB::use( 'reb.open.v1.api.token.sid' )->param( $this->sid );
		}
		return $this->tokenSidKeyDbObj;
	}

	/**
	 * 获取token
	 * @return com\Cla\Com\Token|null
	 */
	public function getTokenOrNull() {
		$dataId = $this->getTokenKeyDbObj()->getOfPath( 'dataId' );
		if( false === $dataId ) return null;
		// 检查数据id是否存在
		$tokenDataIdKeyDbObj = com\Lib\Cache\KeyDB::use( 'reb.open.v1.api.token.dataId' )->param( $dataId );
		$tokenStr = $tokenDataIdKeyDbObj->getOfPath( 'token' );
		if( false === $tokenStr ) return null;
		//
		return new nameToken( $tokenStr );
	}

	/**
	 * 创建token
	 * @param array $param @see nameToken::apply()->$param
	 * @return com\Cla\Com\Token
	 */
	public function createToken( array $param = [] ):cla\Com\Token {
		$tokenObj = nameToken::apply( $param );
		$this->getTokenKeyDbObj()->setOfArray( [
			'dataId' => $tokenObj->data()->getDataId(),
		], $tokenObj->data()->getSupTime() );
		//
		$tokenObj->dataId()->addRelevanceKey( $this->getTokenKeyDbObj()->getKeyName() );
		//
		return $tokenObj;
	}

	/**
	 * 获取或创建token并执行回调函数
	 * @param array $param @see nameToken::apply()->$param
	 * @param \Closure $callback 回调函数：$callback( $tokenObj );
	 * @return com\Cla\Com\Token
	 */
	public function getOrCreateTokenToCallback( \Closure $callback, array $param = [] ):cla\Com\Token {
		$tokenObj = $this->getTokenOrNull();
		if( null !== $tokenObj ) return $tokenObj;
		//
		$tokenObj = $this->createToken( $param );
		$callback( $tokenObj );
		return $tokenObj;
	}

	// ===============================
	//
	//
	// 下面为静态方法
	//
	//
	// ===============================
}
